Skip to content

fix!: isolate DSL class tags across addons - #67

Merged
wemeetagain merged 7 commits into
mainfrom
fix/isolate-addon-type-tags
Aug 13, 2026
Merged

fix!: isolate DSL class tags across addons#67
wemeetagain merged 7 commits into
mainfrom
fix/isolate-addon-type-tags

Conversation

@GrapeBaBa

@GrapeBaBa GrapeBaBa commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Motivation

DSL class tags were derived only from @typeName(T). Separate addons commonly
rooted at mod.zig can therefore both contain mod.Counter and receive the
same napi_type_tag. An exported function accepting *Counter could accept an
object from the other addon, pass napi_check_object_type_tag, and reinterpret
unrelated native memory as its own class.

The identity must also remain stable when the same compiled addon is loaded
from two paths. A process-local address isolates addons, but changes across
reloads and does not provide that stability.

Description

  • add zapi.addAddonIdentity for the final addon owner's build.zig

  • generate zapi_addon_identity from the owner's build.zig.zon package name,
    version, fingerprint, and the final compile-step name

  • derive each class tag as:

    FNV-1a-128(package@version#fingerprint::addon::ZigType)
    
  • pass the generated identity through class registration, constructors,
    methods, accessors, function arguments, and return-value materialization

  • require distinct logical addons in one package to use unique compile-step
    names and separate root modules; aliases and installed copies retain the
    identity embedded in the compiled artifact

  • require .identity = @import("zapi_addon_identity") only when a DSL path
    touches classes; function-only modules may continue to use
    js.exportModule(@This(), .{})

  • expose js.NoAddonIdentity for low-level wrapper/conversion calls that cannot
    accept or return DSL classes

  • document Zig 0.16 local development via zig build --fork=/path/to/zapi,
    because .path dependencies do not expose the dependency's build.zig

  • add behavioral coverage for cross-addon rejection and compatibility between
    two loaded copies of one compiled addon

  • add a function-only addon compile fixture that instantiates
    js.exportModule(@This(), .{})

Breaking change

DSL addons that export or exchange js.class values must:

  1. call zapi.addAddonIdentity for the final .node compile step in their
    build.zig
  2. pass .identity = @import("zapi_addon_identity") to js.exportModule

The public low-level wrapFunction, wrapClass, convertArg,
convertReturn, and callAndConvert APIs now take a comptime identity type.
Class-free callers pass js.NoAddonIdentity. Low-level napi.module.register
users and function-only js.exportModule users are unchanged.

Testing

  • pnpm build
  • pnpm test — 118 JS tests plus Zig tests passed
  • zig build -Doptimize=ReleaseSafe
  • zig build -Dtarget=x86_64-linux-gnu
  • zig build test:example_js_dsl -Doptimize=ReleaseSafe
  • zig build test:example_addon_isolation -Doptimize=ReleaseSafe
  • pnpm lint:js
  • zig fmt --check ...
  • external URL/hash consumer smoke test for zapi.addAddonIdentity

@GrapeBaBa
GrapeBaBa force-pushed the fix/isolate-addon-type-tags branch from 9f761f5 to cfd74ce Compare July 28, 2026 01:32
@GrapeBaBa GrapeBaBa changed the title fix: isolate DSL class tags across addons fix!: isolate DSL class tags across addons Jul 28, 2026
@matthewkeil matthewkeil removed this from the mainnet-blst milestone Jul 28, 2026
@GrapeBaBa
GrapeBaBa marked this pull request as ready for review August 10, 2026 10:03
nazarhussain
nazarhussain previously approved these changes Aug 11, 2026

@nazarhussain nazarhussain left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, one observation.

A package with v1.0.0 and v1.0.1 in the same process would not be able to exchange class objects. While a normal user might think otherway. So we should document this clearly.

…e-tags

# Conflicts:
#	examples/hello_world/mod.test.ts
@wemeetagain
wemeetagain merged commit 3ab8c11 into main Aug 13, 2026
5 checks passed
@github-project-automation github-project-automation Bot moved this from In Progress to Done in Lodestar Team Coordination Aug 13, 2026
@wemeetagain
wemeetagain deleted the fix/isolate-addon-type-tags branch August 13, 2026 20:13
nazarhussain pushed a commit that referenced this pull request Aug 18, 2026
🤖 I have created a release *beep* *boop*
---


##
[4.0.0](zapi-v3.1.0...zapi-v4.0.0)
(2026-08-18)


### ⚠ BREAKING CHANGES

* isolate DSL class tags across addons
([#67](#67))
* manage external buffer lifetime
([#66](#66))
* require writable external buffer storage
([#58](#58))

### Features

* add owned typed arrays
([#68](#68))
([b92c2de](b92c2de))
* **js:** add exact u32 conversion
([#71](#71))
([d6b21e1](d6b21e1))
* **js:** add typed array toArray
([#70](#70))
([ab42ab0](ab42ab0))
* **js:** export module/namespace consts and enums
([#73](#73))
([76dc0db](76dc0db))


### Bug Fixes

* **dsl:** support class pointer arguments
([#50](#50))
([9dd2111](9dd2111))
* harden N-API boundary against JS-triggerable memory bugs
([#60](#60))
([fff76f3](fff76f3))
* isolate DSL class tags across addons
([#67](#67))
([3ab8c11](3ab8c11))
* manage external buffer lifetime
([#66](#66))
([d134a6a](d134a6a))
* **napi:** receive raw pointer out parameters
([#57](#57))
([fde4a9a](fde4a9a))
* remove redundant platform check from musl detection
([#64](#64))
([0d4829c](0d4829c))
* require writable external buffer storage
([#58](#58))
([8fd898f](8fd898f))
* restore registerDecls on Zig 0.16
([#59](#59))
([7f3af3e](7f3af3e))


### Code Refactoring

* **js:** unify env lifecycle refcounting
([#53](#53))
([d3d5056](d3d5056))


### Miscellaneous Chores

* define changelog sections for release-please
([#54](#54))
([1c5e7b4](1c5e7b4))
* update dev deps ([#74](#74))
([5121590](5121590))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

4 participants